package com.example.Windturbine.Service.Impl;

import com.example.Windturbine.Controller.ViewObject.GraphVO.GraphNodeVO;
import com.example.Windturbine.Controller.ViewObject.GraphVO.GraphRelationNode;
import com.example.Windturbine.Controller.ViewObject.GraphVO.GraphVO;
import com.example.Windturbine.Dao.ProductDOMapper;
import com.example.Windturbine.Dao.ProductInfoDOMapper;
import com.example.Windturbine.DataObject.ProductDO;
import com.example.Windturbine.DataObject.ProductInfoDO;
import com.example.Windturbine.Error.BusinessException;
import com.example.Windturbine.Error.EmBusinessError;
import com.example.Windturbine.Response.CommonResult;
import com.example.Windturbine.Service.CacheService;
import com.example.Windturbine.Service.Model.ProductModel;
import com.example.Windturbine.Service.ProductService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author 丁永新
 * @Date 2021/12/17
 */
@Service
public class ProductServiceImpl  implements ProductService {

    @Resource
    ProductDOMapper productDOMapper;




    @Resource
    ProductInfoDOMapper productInfoDOMapper;




    @Autowired
    CacheService cacheService;




    @Override
    public List<ProductModel> getAll() throws BusinessException {

        List<ProductDO> productDOS = productDOMapper.selectAll();
        if(productDOS==null){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"查询产品信息时出现错误！");
        }
        List<ProductModel> productModels=new ArrayList<>();
        for(int i=0;i<productModels.size();i++){
            productModels.add(convertFromProductDO(productDOS.get(i)));
        }
        return productModels;
    }




    @Override
    public List<ProductModel> getUserProduct(Integer id) throws BusinessException {
        List<ProductDO> productDOS = productDOMapper.selectByUserId(id);
        if(productDOS==null){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"查询用户产品信息时出现错误！");
        }
        List<ProductModel> productModels=new ArrayList<>();
        for(int i=0;i<productDOS.size();i++){
            productModels.add(convertFromProductDO(productDOS.get(i)));
        }
        return productModels;
    }


    /**
     * 删除产品相关的数据
     * @param id
     * @throws BusinessException
     */

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
    @Override
    public void deleteById(Integer id)  throws BusinessException {
        try{
            productDOMapper.deleteByPrimaryKey(id);
            productInfoDOMapper.deleteByProductId(id);
        }catch (Exception e){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"删除产品信息出错!");
        }
    }





    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
    public int submitProduct(ProductModel productModel) throws BusinessException {
        ProductDO productDO=new ProductDO();
        BeanUtils.copyProperties(productModel,productDO);
        int i = productDOMapper.insertSelective(productDO);
        if(i==0){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"提交产品信息失败！");
        }
        return productDO.getId();
    }





    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
    public void submitBom(ProductInfoDO productInfoDO) throws BusinessException {

        int i = productInfoDOMapper.insertSelective(productInfoDO);
        if(i==0){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"插入bom表信息时发生意外！");
        }
    }




    /**
     * 查询产品图信息
     * @param productid
     * @return
     */
    @Override
    public CommonResult queryProductGraphInfo(Integer productid) throws BusinessException {

        List<GraphNodeVO> list=new ArrayList<>();

        //获取产品
        ProductDO productDO=productDOMapper.selectByPrimaryKey(productid);
        if(productDO==null){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"计算图形信息时 获取产品信息失败！");
        }

        GraphNodeVO parent=new GraphNodeVO();
        parent.setId(productDO.getId());
        parent.setOrderInfo(productDO.getName());
        parent.setNameInfo(productDO.getName());
        parent.setLevel(0);
        //把产品结点加入list中
        list.add(parent);
        //获取产品下面的所有零件
        List<ProductInfoDO> productInfoDOList=productInfoDOMapper.selectByProductId(productid);
        if(productInfoDOList==null){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"计算图形信息时 获取产品子零件信息失败！");
        }
        try{
            //对零件进行分级
            for(ProductInfoDO productInfoDO:productInfoDOList){
                list.add(convertFromProductInfoDO(productInfoDO,productDO.getName()));
            }

            List<GraphRelationNode> graphRelationNodeList=new ArrayList<>();

            Integer max=0;
            for(GraphNodeVO graphNodeVO:list){
                max=graphNodeVO.getLevel()>max?graphNodeVO.getLevel():max;
                GraphRelationNode g=convertFromNodeVO(graphNodeVO);
                if(g!=null) graphRelationNodeList.add(g);
            }

            GraphVO result=new GraphVO(max,list,graphRelationNodeList);
            return CommonResult.create(result);
        }catch (Exception e){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"零件分级过程中出现错误！");
        }

    }





    @Override
    public List<ProductInfoDO> getProductInfo(Integer id)  throws BusinessException{
        try{
            List<ProductInfoDO> productInfoDOList=productInfoDOMapper.selectByProductId(id);
            if(productInfoDOList==null){
                throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"获取失败！");
            }
            return productInfoDOList;
        }catch (Exception e){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"获取产品详情出错!");
        }

    }




    private ProductModel convertFromProductDO(ProductDO productDO){
        if(productDO==null){
            return null;
        }
        ProductModel productModel=new ProductModel();
        BeanUtils.copyProperties(productDO,productModel);
        return productModel;
    }


    private ProductModel convertFromProductInfoDO(List<ProductInfoDO> productInfoDOList){
        if(productInfoDOList==null){
            return null;
        }
        ProductModel productModel=new ProductModel();
        BeanUtils.copyProperties(productInfoDOList,productModel);
        return productModel;
    }


    private ProductModel convertFromDOAndInfoDO(ProductDO productDO,List<ProductInfoDO> productInfoDOList){
        if(productInfoDOList==null||productDO==null){
            return null;
        }
        ProductModel productModel=new ProductModel();
        BeanUtils.copyProperties(productDO,productModel);
        productModel.setProductInfoDOList(productInfoDOList);
        return productModel;
    }

    private GraphNodeVO convertFromProductInfoDO(ProductInfoDO productInfoDO,String parentName){
        GraphNodeVO graphNodeVO=new GraphNodeVO();
        BeanUtils.copyProperties(productInfoDO,graphNodeVO);
        String order=productInfoDO.getOrderInfo();
        String[] orders=order.split("\\.");
        //设置等级
        graphNodeVO.setLevel(orders.length);
        //设置父节点
        if(orders.length==1){
            //他们的父零件就是产品本身
            graphNodeVO.setParentorder(parentName);
        }else{
            //他们的父节点就是小数点前一串字母
            int lastdotindex=0;
            for(int i=order.length()-1;i>=0;i--){
                if(order.charAt(i)=='.'){
                    lastdotindex=i;
                    break;
                }
            }
            graphNodeVO.setParentorder(order.substring(0,lastdotindex));
        }
        return graphNodeVO;

    }

    private GraphRelationNode convertFromNodeVO(GraphNodeVO graphNodeVO){
        if(graphNodeVO.getLevel()==null){
            return null;
        }
        GraphRelationNode graphRelationNode=new GraphRelationNode();
        graphRelationNode.setParent(graphNodeVO.getParentorder());
        graphRelationNode.setChild(graphNodeVO.getOrderInfo());
        graphRelationNode.setName(graphNodeVO.getLevel()+"级零件");
        graphRelationNode.setDes("无");
        return graphRelationNode;
    }



}
